package proyecto.testcasetool.presentation.details.usecase;

import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.edit.command.SetCommand;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.emf.edit.provider.AdapterFactoryItemDelegator;
import org.eclipse.emf.edit.provider.IItemPropertyDescriptor;
import org.eclipse.emf.edit.provider.ItemProvider;
import org.eclipse.emf.edit.ui.celleditor.FeatureEditorDialog;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider;
import org.eclipse.emf.edit.ui.provider.ExtendedImageRegistry;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.ListViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.FocusAdapter;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.List;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.forms.IFormPart;
import org.eclipse.ui.forms.widgets.ExpandableComposite;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.Section;

import proyecto.testcasetool.Actor;
import proyecto.testcasetool.Condition;
import proyecto.testcasetool.Subject;
import proyecto.testcasetool.TestcasetoolFactory;
import proyecto.testcasetool.TestcasetoolPackage;
import proyecto.testcasetool.UseCase;
import proyecto.testcasetool.UseCaseModel;
import proyecto.testcasetool.presentation.details.DetailsPage;
import proyecto.testcasetool.presentation.editor.TestcasetoolEditorPlugin;
import proyecto.testcasetool.presentation.editor.pages.FormLayoutFactory;
import proyecto.testcasetool.provider.TestcasetoolEditPlugin;



public class UseCaseDetailsPage extends DetailsPage {
	private Text txtUsecasename;
	private Text txtDescription;
	private Text txtPreConditions;
	private Text txtPostConditions;
	
	private AdapterFactoryItemDelegator afid;
	private ListViewer listViewer;
	private ListViewer listViewerIncludedCases;
	
	public UseCaseDetailsPage(FormToolkit toolkit, EditingDomain editingDomain,
			AdapterFactory adapterFactory) {
		super(toolkit, editingDomain, adapterFactory);
		afid =  new AdapterFactoryItemDelegator(adapterFactory);
	}

	@Override
	protected void createDetailsSection(final Composite parent) {
		GridLayout gridLayout = (GridLayout) parent.getLayout();
		gridLayout.verticalSpacing = 5;

		Section s = toolkit.createSection(parent, Section.TITLE_BAR);
		s.setText("Use case details");
		s.setLayoutData(new GridData(GridData.FILL_BOTH));
		s.setLayout(FormLayoutFactory.createDetailsGridLayout(false, 1));
		
		Composite client = toolkit.createComposite(s,SWT.FILL);
		
		s.setClient(client);
		client.setLayout(new GridLayout(2, false));
		toolkit.paintBordersFor(client);
		
		Label lblName = toolkit.createLabel(client, "Name", SWT.NONE);
		GridData gd_lblName = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1);
		gd_lblName.verticalIndent = 2;
		lblName.setLayoutData(gd_lblName);
		
		txtUsecasename = toolkit.createText(client, "New Text", SWT.NONE);
		
		txtUsecasename.addModifyListener(new ModifyListener() {
			public void modifyText(ModifyEvent e) {
				IItemPropertyDescriptor desc = afid.getPropertyDescriptor(eObject,
						TestcasetoolPackage.Literals.USE_CASE__NAME);
				desc.setPropertyValue(eObject, ((Text) e.widget).getText());
			}
		});
		
		GridData gd_txtUsecasename = new GridData(SWT.LEFT, SWT.CENTER, true, false, 1, 1);
		gd_txtUsecasename.verticalIndent = 2;
		gd_txtUsecasename.widthHint = 244;
		txtUsecasename.setLayoutData(gd_txtUsecasename);
		
		Label lblDescription = toolkit.createLabel(client, "Description", SWT.NONE);
		txtDescription = toolkit.createText(client, "", SWT.WRAP | SWT.V_SCROLL | SWT.MULTI);
		
		txtDescription.addFocusListener(new FocusAdapter() {
			@Override
			public void focusLost(FocusEvent e) {
				IItemPropertyDescriptor desc = afid.getPropertyDescriptor(
						eObject,
						TestcasetoolPackage.Literals.USE_CASE__DESCRIPTION);
				desc.setPropertyValue(eObject,
						((Text) e.widget).getText());
			}
		});
		
		GridData gd_txtDescription = new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1);
		gd_txtDescription.heightHint = 80;
		gd_txtDescription.verticalIndent = 10;
		gd_txtDescription.widthHint = 0;
		txtDescription.setLayoutData(gd_txtDescription);
		
		Label lblPrecondition = toolkit.createLabel(client, "Pre-conditions", SWT.NONE);
		txtPreConditions = toolkit.createText(client, "", SWT.WRAP | SWT.V_SCROLL | SWT.MULTI);
		
		txtPreConditions.addFocusListener(new FocusAdapter() {
			@Override
			public void focusLost(FocusEvent e) {
				UseCase useCase = (UseCase)eObject;
				if (useCase.getPreCondition() != null){
					IItemPropertyDescriptor desc = afid.getPropertyDescriptor(
							useCase.getPreCondition(),
							TestcasetoolPackage.Literals.CONDITION__EXPRESSION);
					desc.setPropertyValue(useCase.getPreCondition(),
							((Text) e.widget).getText());
				}
				else{
			    	  Condition condition = TestcasetoolFactory.eINSTANCE.createCondition();
			    	  condition.setExpression(((Text) e.widget).getText());
			    	  Command cmd = SetCommand.create(editingDomain, eObject, TestcasetoolPackage.Literals.USE_CASE__PRE_CONDITION, condition);
			    	  editingDomain.getCommandStack().execute(cmd);
				}
				
			}
		});
		
		
		GridData gd_txtPreConditions = new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1);
		gd_txtPreConditions.heightHint = 80;
		gd_txtPreConditions.verticalIndent = 10;
		gd_txtPreConditions.widthHint = 0;
		txtPreConditions.setLayoutData(gd_txtPreConditions);
		
		Label lblPostcondition = toolkit.createLabel(client, "Post-conditions", SWT.NONE);
		
		txtPostConditions = toolkit.createText(client, "", SWT.WRAP | SWT.V_SCROLL | SWT.MULTI);
		
		txtPostConditions.addFocusListener(new FocusAdapter() {
			@Override
			public void focusLost(FocusEvent e) {
				UseCase useCase = (UseCase)eObject;
				if (useCase.getPosCondition() != null){
					IItemPropertyDescriptor desc = afid.getPropertyDescriptor(
							useCase.getPosCondition(),
							TestcasetoolPackage.Literals.CONDITION__EXPRESSION);
					desc.setPropertyValue(useCase.getPosCondition(),
							((Text) e.widget).getText());
				}
				else{
			    	  Condition condition = TestcasetoolFactory.eINSTANCE.createCondition();
			    	  condition.setExpression(((Text) e.widget).getText());
			    	  Command cmd = SetCommand.create(editingDomain, eObject, TestcasetoolPackage.Literals.USE_CASE__POS_CONDITION, condition);
			    	  editingDomain.getCommandStack().execute(cmd);
				}
			}
		});
		
		GridData gd_txtPostConditions = new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1);
		gd_txtPostConditions.heightHint = 80;
		gd_txtPostConditions.verticalIndent = 10;
		gd_txtPostConditions.widthHint = 380;
		txtPostConditions.setLayoutData(gd_txtPostConditions);
		toolkit.paintBordersFor(client);
		
		Composite sectionsActorsAndIncludedCases = toolkit.createComposite(parent,SWT.FILL);
		sectionsActorsAndIncludedCases.setLayout(new GridLayout(2, true));
		sectionsActorsAndIncludedCases.setLayoutData(new GridData(GridData.FILL_BOTH));
		
		createActorsSection(sectionsActorsAndIncludedCases);
		
		createIncludedCasesSection(sectionsActorsAndIncludedCases);
		
		
	}
	
	public void selectionChanged(IFormPart part, ISelection selection) {
		// controlar que sea la part que esto esperando!!!!
		if (!(selection instanceof IStructuredSelection)) {
			return;
		}
		EObject newEObject = getEObjectFromSelection(selection);
		if (newEObject != null && newEObject != eObject) {
			eObject = newEObject;
			if (eObject != null) {
				System.out.println("UseCaseDetailsPage.selectionChanged"+
						"\n"+part+"\n"+selection);
				fillContents();
				
			}
		}
	}

	private void fillContents() {
		UseCase useCase = (UseCase)eObject;
		if (useCase.getName() != null){
			txtUsecasename.setText(useCase.getName());
		}
		if (useCase.getDescription() != null){
			txtDescription.setText(useCase.getDescription());
		}
		if (useCase.getPreCondition() != null){
			txtPreConditions.setText(useCase.getPreCondition().getExpression());
		}
		if (useCase.getPosCondition() != null){
			txtPostConditions.setText(useCase.getPosCondition().getExpression());
		}

		refreshActors();
		refreshIncludedCases();
	}
	
	private void refreshActors(){
		ItemProvider listRoot = new ItemProvider("Actors",
				TestcasetoolEditPlugin.INSTANCE.getImage("full/obj16/Actor"),
				((UseCase)eObject).getParticipantActor());
		listViewer.setInput(listRoot);
	}

	private void refreshIncludedCases() {
		ItemProvider listRoot = new ItemProvider("Included usecases",
				TestcasetoolEditPlugin.INSTANCE.getImage("full/obj16/UseCase"),
				((UseCase)eObject).getIncludeCase());
		listViewerIncludedCases.setInput(listRoot);
		
	}
	
	private void createActorsSection(final Composite parent) {
		Section sectionActors = toolkit.createSection(parent,
				ExpandableComposite.EXPANDED | ExpandableComposite.TITLE_BAR);
		sectionActors.setText("Use case actors");
		sectionActors.setLayoutData(new GridData(GridData.FILL_BOTH));
		sectionActors.setLayout(FormLayoutFactory.createDetailsGridLayout(false, 1));
		
		Composite compositeActors = toolkit.createComposite(sectionActors, SWT.NONE);
		sectionActors.setClient(compositeActors);
		compositeActors.setLayout(new GridLayout(2, false));
		new Label(compositeActors, SWT.NONE);
		
		Button b = toolkit.createButton(compositeActors, "OK", SWT.PUSH);
		b.setLayoutData(new GridData(SWT.RIGHT, SWT.BOTTOM, false, false, 1, 1));
		b.addSelectionListener(new SelectionListener() {
			
			@Override
			public void widgetSelected(SelectionEvent e) {
				UseCase useCase = (UseCase)eObject;
				UseCaseModel model = (UseCaseModel)EcoreUtil.getRootContainer(useCase);
				
				final ILabelProvider labelProvider = new LabelProvider()
			      {
			        @Override
			        public String getText(Object object)
			        {
			          if (object instanceof UseCase){
			        	  return ((UseCase)object).getName();
			          }
			          else if(object instanceof Actor){
			        	  return ((Actor)object).getName();
			          }
			          return "";
			        }
			        @Override
			        public Image getImage(Object object)
			        {
			        	//return null;
			          return ExtendedImageRegistry.getInstance().getImage(TestcasetoolEditorPlugin.getPlugin().getImage("32px-Crystal_Clear_app_kword.png"));
			        }
			      };
			      IItemPropertyDescriptor desc = afid.getPropertyDescriptor(eObject,
							TestcasetoolPackage.Literals.USE_CASE__PARTICIPANT_ACTOR);
			      EStructuralFeature feature = (EStructuralFeature)desc.getFeature(eObject);
				FeatureEditorDialog dialog = new FeatureEditorDialog(parent.getShell(), labelProvider,eObject, feature.getEType(),useCase.getParticipantActor(), "Actor", model.getActor(), false,true,true);
				dialog.open();
				
				EList<Actor> result = (EList<Actor>)dialog.getResult();
				desc.setPropertyValue(eObject, result);
				refreshActors();
				
			}

			@Override
			public void widgetDefaultSelected(SelectionEvent e) {
			}
			
		});
	
		
		
		Label lblActorsInvolved = toolkit.createLabel(compositeActors, "Actors", SWT.NONE);
		lblActorsInvolved.setToolTipText("Participant actors");
		listViewer = new ListViewer(compositeActors, SWT.BORDER | SWT.V_SCROLL);
		List list = listViewer.getList();
		GridData gd_list = new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1);
		gd_list.heightHint = 80;
		list.setLayoutData(gd_list);
		listViewer.setContentProvider(new AdapterFactoryContentProvider(adapterFactory));
		listViewer.setLabelProvider(new AdapterFactoryLabelProvider(adapterFactory){
					
					@Override
					public String getText(Object object) {
						return ((Actor)object).getName();
					}
					
					@Override
					public Image getImage(Object object) {
						  return ExtendedImageRegistry.getInstance().getImage(TestcasetoolEditorPlugin.getPlugin().getImage("32px-Crystal_Clear_app_kword.png"));
					}
					
				});

	}
	
	private void createIncludedCasesSection(final Composite parent) {
		Section sectionIncludedCases = toolkit.createSection(parent,
				ExpandableComposite.EXPANDED | ExpandableComposite.TITLE_BAR);
		sectionIncludedCases.setText("Included use cases");
		sectionIncludedCases.setLayoutData(new GridData(GridData.FILL_BOTH));
		sectionIncludedCases.setLayout(FormLayoutFactory.createDetailsGridLayout(false, 1));
		
		Composite compositeIncludedCases = toolkit.createComposite(sectionIncludedCases, SWT.NONE);
		sectionIncludedCases.setClient(compositeIncludedCases);
		compositeIncludedCases.setLayout(new GridLayout(2, false));
		// esto es para estar en la segunda columna
		new Label(compositeIncludedCases, SWT.NONE);
		
		Button b = toolkit.createButton(compositeIncludedCases, "Add", SWT.PUSH);
		b.setLayoutData(new GridData(SWT.RIGHT, SWT.BOTTOM, false, false, 1, 1));
		b.addSelectionListener(new SelectionListener() {
			
			@Override
			public void widgetSelected(SelectionEvent e) {
				UseCase useCase = (UseCase)eObject;
				UseCaseModel model = (UseCaseModel)EcoreUtil.getRootContainer(useCase);
				Subject system = model.getSubject();
				final ILabelProvider labelProvider = new LabelProvider()
			      {
			        @Override
			        public String getText(Object object)
			        {
			          if (object instanceof UseCase){
			        	  return ((UseCase)object).getName();
			          }
			          else if(object instanceof Subject){
			        	  return "hola";//((Subject)object).getName();
			          }
			          return "";
			        }
			        @Override
			        public Image getImage(Object object)
			        {
			        	//return null;
			          return ExtendedImageRegistry.getInstance().getImage(TestcasetoolEditorPlugin.getPlugin().getImage("32px-Crystal_Clear_app_kword.png"));
			        }
			      };
			      IItemPropertyDescriptor desc = afid.getPropertyDescriptor(eObject,
							TestcasetoolPackage.Literals.USE_CASE__INCLUDE_CASE);
			      EStructuralFeature feature = (EStructuralFeature)desc.getFeature(eObject);
				FeatureEditorDialog dialog = new FeatureEditorDialog(parent.getShell(), labelProvider,eObject, feature.getEType(),useCase.getIncludeCase(), "IncludedCase", system.getUseCase(), false,true,true);
				dialog.open();
				
				EList<UseCase> result = (EList<UseCase>)dialog.getResult();
				desc.setPropertyValue(eObject, result);
				refreshIncludedCases();
				
			}

			@Override
			public void widgetDefaultSelected(SelectionEvent e) {
			}
			
		});
		
		Label lblIncludedCases = toolkit.createLabel(compositeIncludedCases, "Use cases", SWT.NONE);
		listViewerIncludedCases = new ListViewer(compositeIncludedCases, SWT.BORDER | SWT.V_SCROLL);
		List list = listViewerIncludedCases.getList();
		GridData gd_list = new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1);
		gd_list.heightHint = 80;
		list.setLayoutData(gd_list);
		listViewerIncludedCases.setContentProvider(new AdapterFactoryContentProvider(adapterFactory));
		listViewerIncludedCases.setLabelProvider(new AdapterFactoryLabelProvider(adapterFactory));

	}
}